/************************************************************************
 * The code is owned by mainframer.cn and Shang Tao
 * Without aproval of mainframer.cn and Shang Tao, removing the copyright
 * infomation is regarded as invassion of proprietary copyright
 ***********************************************************************/
package com.mr.qa.dao.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.criterion.Example;

import com.mr.qa.bo.SharedFile;
import com.mr.qa.bo.SharedFileCategory;
import com.mr.qa.exception.QaException;

/**
 * Data access object (DAO) for domain model class SharedFile.
 * @see
 * @author
 */
public class SharedFileDAO extends BaseHibernateDAO 
{
    private static final Log log = LogFactory.getLog(SharedFileDAO.class);
    //property constants
    public static final String NAME = "name";
    public static final String PATH = "path";
    public static final String DOWNLOAD_COUNT = "downloadCount";

    public void save(SharedFile transientInstance) 
    {
        try 
        {
            getSession().save(transientInstance);
        }
        catch(RuntimeException re) 
        {
            throw re;
        }
    }

    public void modify(SharedFile transientInstance) 
    {
        try 
        {
            getSession().update(transientInstance);
        }
        catch(RuntimeException re) 
        {
            throw re;
        }
    }

    
    public void delete(SharedFile persistentInstance) 
    {
        log.debug("deleting SharedFile instance");
        try 
        {
            getSession().delete(persistentInstance);
            log.debug("delete successful");
        }
        catch (RuntimeException re) 
        {
            log.error("delete failed", re);
            throw re;
        }
    }
    
    public SharedFile findById( java.lang.Integer id)
    {
        log.debug("getting SharedFile instance with id: " + id);
        try
        {
            SharedFile instance = (SharedFile) getSession()
                    .get("com.mr.qa.bo.SharedFile", id);
            return instance;
        }
        catch (RuntimeException re) 
        {
            log.error("get failed", re);
            throw re;
        }
    }
    
    
    public void download(String path)
    {
        try
        {
            List list = findByProperty("path",path);
            System.out.println("by path:"+path+" list="+list.size());
            if(list.size() > 0)
            {
                SharedFile sf = (SharedFile)list.get(0);
                System.out.println("sf path:"+sf.getPath());
                sf.setDownloadCount(sf.getDownloadCount()+1);
            }
        }
        catch(Exception e)
        {
            
        }
    }
    
    public List findByExample(SharedFile instance) {
        log.debug("finding SharedFile instance by example");
        try {
            List results = getSession()
                    .createCriteria("com.mr.qa.bo.SharedFile")
                    .add(Example.create(instance))
            .list();
            log.debug("find by example successful, result size: " + results.size());
            return results;
        } catch (RuntimeException re) {
            log.error("find by example failed", re);
            throw re;
        }
    }    
    
    public List mylist(Integer userId)
    {
//       return findByProperty("mrIaskUser.id",userId);
	    String queryString = "from SharedFile as model where model.mrIaskUser.id = ? " +
                "order by model.postDate desc";
	    Query queryObject = getSession().createQuery(queryString);
	    queryObject.setParameter(0, userId);
        //queryObject.setParameter(1, "1");
	    if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
	    {
	        queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
	        queryObject.setMaxResults(getRecordCount().intValue());
	    }
        return queryObject.list();

    }
    public List hislist(Integer userId)
    {
	    String queryString = "from SharedFile as model where model.mrIaskUser.id = ? " +
                "and model.state != ? order by model.postDate desc";
	    Query queryObject = getSession().createQuery(queryString);
	    queryObject.setParameter(0, userId);
        queryObject.setParameter(1, "1");
	    if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
	    {
	        queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
	        queryObject.setMaxResults(getRecordCount().intValue());
	    }
        return queryObject.list();
    }

    public int countMylist(Integer userId)
    {
       String queryString = "select count(*) from SharedFile as model where model.mrIaskUser.id = ?";
       HashMap parameters = new HashMap();
       parameters.put(0, userId);
       return this.countQuery(queryString,parameters);
    }
    public int countHislist(Integer userId)
    {
       String queryString = "select count(*) from SharedFile as model where model.mrIaskUser.id = ? and model.state != ?";
       HashMap parameters = new HashMap();
       parameters.put(0, userId);
       parameters.put(1, "1");
       return this.countQuery(queryString,parameters);
     }
    
    public int countHislistDownloaded(Integer userId)
    {
       String queryString = "select sum(downloadCount) from SharedFile as model where model.mrIaskUser.id = ? and model.state != ?";
       HashMap parameters = new HashMap();
       parameters.put(0, userId);
       parameters.put(1, "1");
       return this.countQuery(queryString,parameters);
     }


    public List findByProperty(String propertyName, Object value) {
      log.debug("finding SharedFile instance with property: " + propertyName
            + ", value: " + value);
      try {
         String queryString = "from SharedFile as model where model." 
         						+ propertyName + "= ?";
         Query queryObject = getSession().createQuery(queryString);
		 queryObject.setParameter(0, value);
		 return queryObject.list();
      } catch (RuntimeException re) {
         log.error("find by property name failed", re);
         throw re;
      }
	}
        /**
         * select all shared files according to name
         * @param name
         * @return
         */
	public List findByName(Object name) 
    {
	    String queryString = "from SharedFile as model where model.name like ?";
	    Query queryObject = getSession().createQuery(queryString);
	    queryObject.setParameter(0, "%"+name+"%");
	    if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
	    {
	        queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
	        queryObject.setMaxResults(getRecordCount().intValue());
	    }
            return queryObject.list();            
	}
        
    public SharedFile findByFilePath(String filePath) 
    {
        String queryString = "from SharedFile as model where model.path like ?";
        Query queryObject = getSession().createQuery(queryString);
        //log.info("filePath:"+filePath);
        queryObject.setParameter(0, "%"+filePath+"%");
        if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
        {
            queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
            queryObject.setMaxResults(getRecordCount().intValue());
        }
        return (SharedFile)queryObject.list().get(0);            
    }
        
        
        
    public List search(String searchText)
    {
        String queryString = "from SharedFile as model where (model.name like ? or " +
        "model.description like ?) and model.state != ?";
        HashMap parameters = new HashMap();
        parameters.put(0,"%"+searchText+"%");
        parameters.put(1,"%"+searchText+"%");
        parameters.put(2,"1");
        return this.getQueryList(queryString,parameters);
    }

    public int countSearch(String searchText) 
    {
        String queryString = "select count(*) from SharedFile as model where (model.name like ? or " +
        "model.description like ?) and model.state != ?";
        HashMap parameters = new HashMap();
        parameters.put(0,"%"+searchText+"%");
        parameters.put(1,"%"+searchText+"%");
        parameters.put(2,"1");
        return this.countQuery(queryString,parameters);
    }

        
    /**
     * select all shared files which have no parent
     * @return
     */
    public List findSharedFiles() 
    {
        String queryString = "from SharedFile as model where model.state != '1' order by model.id desc,model.downloadCount desc";
        return this.getQueryList(queryString,null);
    }

    public int countSharedFiles() 
    {
        String queryString = "select count(*) from SharedFile as model where model.state != '1'";
        return this.countQuery(queryString,null);
    }
     /**
      * select all shared files directly under cat
      * @return
      */
     public List findSharedFilesUnderACategoryForAdmin(int categoryId) 
     {
         String queryString = "from SharedFile as model where model.mrIaskSharedFileCategory.id = ? " +
         "order by model.id desc,model.downloadCount desc";
         HashMap parameters = new HashMap();
         parameters.put(0,categoryId);
         return this.getQueryList(queryString,parameters);
         /*
         Query queryObject = getSession().createQuery(queryString);
         if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
         {
             queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
             queryObject.setMaxResults(getRecordCount().intValue());
         }
         return queryObject.list();
         */
     }
     //directly under cat   
     public int countSharedFilesUnderACategoryForAdmin(int categoryId) 
     {
         String queryString = "select count(*) from SharedFile as model where model.mrIaskSharedFileCategory.id = ?";
         HashMap parameters = new HashMap();
         parameters.put(0,categoryId);
         /*
         Query queryObject = getSession().createQuery(queryString);
         long longCount = (Long)queryObject.uniqueResult();
         return new Integer(""+longCount);
         */
         return this.countQuery(queryString,parameters);
     }
    
    /**
     * select all shared files which have no parent
     * @return
     */
    public List findAllRecommendedSharedFiles() 
    {
        String queryString = "from SharedFile as model where model.state != ? and " +
        "model.isRecommended = ? order by model.id desc";
        HashMap parameters = new HashMap();
        parameters.put(0,"1");
        parameters.put(1,Boolean.TRUE);
        return this.getQueryList(queryString,parameters);
        
        /*
        Query queryObject = getSession().createQuery(queryString);
        if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
        {
            queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
            queryObject.setMaxResults(getRecordCount().intValue());
        }
        return queryObject.list();*/
    }

    public int countAllRecommendedSharedFiles() 
    {
        String queryString = "select count(*) from SharedFile as model " +
        "where model.state != ? and model.isRecommended = ?";
        HashMap parameters = new HashMap();
        parameters.put(0,"1");
        parameters.put(1,Boolean.TRUE);
        return this.countQuery(queryString,parameters);
        /*
        Query queryObject = getSession().createQuery(queryString);
        long longCount = (Long)queryObject.uniqueResult();
        return new Integer(""+longCount);
        */
    }


    /**
     * select all shared files which have no parent
     * @return
     */
    public List rankSharedFiles() 
    {
        String queryString = "from SharedFile as model where model.state != '1' order by model.downloadCount desc";
        return this.getQueryList(queryString,null);
        /*
        Query queryObject = getSession().createQuery(queryString);
        if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
        {
            queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
            queryObject.setMaxResults(getRecordCount().intValue());
        }
        return queryObject.list();*/
    }
    
    
    
    /**
     * find all shared files under a SharedFileCategory including its child SharedFileCategory
     * @param sfc
     * @return
     * @throws QaException
     */
    public List findAllSharedFilesUnderSharedFileCategory(SharedFileCategory sfc) throws QaException
    {
        String queryString = makeSharedFileQueryString(sfc,null,"model");
        return this.getQueryList(queryString,null);
        /*
        Query queryObject = getSession().createQuery(queryString);
        if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
        {
            queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
            queryObject.setMaxResults(getRecordCount().intValue());
        }
        return queryObject.list();
        */
    }
    /**
     * find all shared files under a SharedFileCategory including its child SharedFileCategory
     * @param sfc
     * @return
     * @throws QaException
     */
    public int countAllSharedFilesUnderSharedFileCategory(SharedFileCategory sfc) throws QaException
    {
        //log.info("sfc id="+sfc.getId());
        String queryString = makeSharedFileQueryString(sfc,null,"count(*)");
        return this.countQuery(queryString,null);
        //log.info("queryString="+queryString);
        /*
        Query queryObject = getSession().createQuery(queryString);
        if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
        {
            queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
            queryObject.setMaxResults(getRecordCount().intValue());
        }
        long longCount = (Long)queryObject.uniqueResult();
        return new Integer(""+longCount);*/
    }

    /**
     * find all shared files under a SharedFileCategory including its child SharedFileCategory
     * @param sfc
     * @return
     * @throws QaException
     */
    public List findAllRecommendedSharedFilesUnderSharedFileCategory(SharedFileCategory sfc) throws QaException
    {
        String queryString = makeSharedFileQueryString(sfc,"model.isRecommended = true","model");
        return this.getQueryList(queryString,null);
        /*
        //log.info("queryString="+queryString);
        Query queryObject = getSession().createQuery(queryString);
        if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
        {
            queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
            queryObject.setMaxResults(getRecordCount().intValue());
        }
        return queryObject.list();*/
    }

    /**
     * find all shared files under a SharedFileCategory including its child SharedFileCategory
     * @param sfc
     * @return
     * @throws QaException
     */
    public int countAllRecommendedSharedFilesUnderSharedFileCategory(SharedFileCategory sfc) throws QaException
    {
        //log.info("sfc id="+sfc.getId());
        String queryString = makeSharedFileQueryString(sfc,"model.isRecommended = true","count(*)");
        return this.countQuery(queryString,null);
        /*
        //log.info("queryString="+queryString);
        Query queryObject = getSession().createQuery(queryString);
        if(this.getPageNo().intValue() > 0 && this.getRecordCount().intValue() > 0)
        {
            queryObject.setFirstResult((getPageNo().intValue() - 1) * getRecordCount().intValue());
            queryObject.setMaxResults(getRecordCount().intValue());
        }
        long longCount = (Long)queryObject.uniqueResult();
        return new Integer(""+longCount);*/
    }
    
    /**
     * make query string for selecting sharedfile, this method loops through the hirarchy of SharedFileCategory
     * 
     * @param sfc
     * @param whereString
     * @param queryType "count(*) or distinct model"
     * @return
     * @throws QaException
     */
    private String makeSharedFileQueryString(SharedFileCategory sfc, String whereString,String queryType) throws QaException
    {
        if(sfc == null)throw new QaException("Shared File Category required");
        String queryString = "";
        Integer sfcId = sfc.getId();
        if(sfcId == null)throw new QaException("Shared File Category Id required");
        Integer level = sfc.getLevel();
        if(whereString == null || whereString.length() == 0)
           queryString = "select "+queryType+" from SharedFile as model where model.state != '1' and model.mrIaskSharedFileCategory.id in ";
        else
           queryString = "select "+queryType+" from SharedFile as model where "+whereString+" and model.state != '1' and model.mrIaskSharedFileCategory.id in ";
        String inWhereString = "";
        //log.info("para sfc level="+level.intValue());
        if(level.intValue() == 1)
        {
            Collection level2Sfcs = sfc.getMrIaskSharedFileCategories();
            if(level2Sfcs.size() == 0)//no level 2
            {
                inWhereString = "'"+sfc.getId()+"'";
            }
            else//level 2 exist
            {
                //log.info("para sfc child size="+level2Sfcs.size());
                inWhereString = "'"+sfc.getId()+"'";
                Iterator level2Iterator = level2Sfcs.iterator();
                SharedFileCategory level2SharedFileCategory = null;
                SharedFileCategory level3SharedFileCategory = null;
                Iterator level3Iterator = null;
                Collection level3Sfcs = null;
                while(level2Iterator.hasNext())
                {
                    level2SharedFileCategory = (SharedFileCategory)level2Iterator.next();
                    level3Sfcs = level2SharedFileCategory.getMrIaskSharedFileCategories();
                    if(level3Sfcs.size() > 0)//level 2 has level 3
                    {
                        inWhereString += ",'"+level2SharedFileCategory.getId()+"'";//new
                        level3Iterator = level3Sfcs.iterator();
                        while(level3Iterator.hasNext())
                        {
                            level3SharedFileCategory = (SharedFileCategory)level3Iterator.next();
                            //or cause
                            if(inWhereString.length() == 0)
                                inWhereString = "'"+level3SharedFileCategory.getId()+"'";
                            else
                                inWhereString = inWhereString+",'"+level3SharedFileCategory.getId()+"'";
                        }
                    }
                    else//leve2 has no level 3
                    {
                        //or cause
                         if(inWhereString.length() == 0)
                             inWhereString = "'"+level2SharedFileCategory.getId()+"'";
                         else
                             inWhereString += ",'"+level2SharedFileCategory.getId()+"'";
                        
                    }
                }
            }
        }
        else if(level.intValue() == 2)
        {
            Collection level3Sfcs = sfc.getMrIaskSharedFileCategories();
            if(level3Sfcs.size() > 0)
            {
                inWhereString = "'"+sfc.getId()+"'";//new
                Iterator level3Iterator = level3Sfcs.iterator();
                SharedFileCategory level3SharedFileCategory = null;
                while(level3Iterator.hasNext())
                {
                    level3SharedFileCategory = (SharedFileCategory)level3Iterator.next();
                    //or cause
                     if(inWhereString.length() == 0)
                         inWhereString = "'"+level3SharedFileCategory.getId()+"'";
                     else
                         inWhereString += ",'"+level3SharedFileCategory.getId()+"'";
                }
            }
            else
            {
                inWhereString = "'"+sfc.getId()+"'";
            }
        }
        else if(level.intValue() == 3)
        {
            inWhereString = "'"+sfc.getId()+"'";
        }
        inWhereString = "("+inWhereString+")";
        if("count(*)".equals(queryType))
            queryString = queryString+inWhereString;
        else
            queryString = queryString+inWhereString+" order by model.id desc,model.downloadCount desc";
        return queryString;
    }//end
    
}